// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	8/4/2013 3:34:21 PM				
// -----------------------------

#include "LuaStack.h"
#include "Lua.h"
#include "LuaIncl.h"
#include "LuaTable.h"

namespace ObjectLua
{

	LuaStack::LuaStack(Lua* lpLua)
		: LuaObject(lpLua)
	{
	}
	
	LuaStack::~LuaStack()
	{
	}

	
	LuaStackDump LuaStack::stackDump()
	{
		LuaStackDump stackDump;
		return stackDump;
	}
	void LuaStack::pop(int idx)
	{
		lua_pop(m_lpLua->getState(),idx);
	}
	int LuaStack::upValueIndex(int idx)
	{
		return lua_upvalueindex(idx);
	}
	void LuaStack::setTable(int idx)
	{
		lua_settable(m_lpLua->getState(),idx);
	}
	void LuaStack::setMetaTable(int idx)
	{
		lua_setmetatable(m_lpLua->getState(),idx);
	}

	void LuaStack::setupvalue(int idx, int upIdx)
	{
		lua_setupvalue(m_lpLua->getState(), idx, upIdx);
	}
	int LuaStack::getTop()
	{
		return lua_gettop(m_lpLua->getState());
	}
	void* LuaStack::requestUserData(size_t size)
	{
		return lua_newuserdata(m_lpLua->getState(),size);
	}
	void LuaStack::requestMetaTable(const char* lpName)
	{
		luaL_newmetatable(m_lpLua->getState(), lpName);
	}
	void LuaStack::requestTable()
	{
		lua_newtable(m_lpLua->getState());
	}
	void LuaStack::registerFunctions(const int funcCount, LuaReg functions[])
	{
		for(int i = 0; i < funcCount; ++i)
			lua_register(m_lpLua->getState(), functions[i].Name, (lua_CFunction) functions[i].Function);
	}
	void LuaStack::pushValue(int idx)
	{
		lua_pushvalue(m_lpLua->getState(),idx);
	}

	void LuaStack::setField(int idx, const char* name)
	{
		lua_setfield(m_lpLua->getState(), idx, name);
	}
	void LuaStack::setGlobal(const char* name)
	{
		lua_setglobal(m_lpLua->getState(), name);
	}

	void LuaStack::pushInteger(int i)
	{
		lua_pushinteger(m_lpLua->getState(),i);
	}
	void LuaStack::pushBool(bool b)
	{
		lua_pushboolean(m_lpLua->getState(), (int) b);
	}
	void LuaStack::pushNumber(double d)
	{
		lua_pushnumber(m_lpLua->getState(),d);
	}
	void LuaStack::pushString(const char* lpStr)
	{
		LUA_ASSERT(lpStr);
		lua_pushstring(m_lpLua->getState(),lpStr);
	}
	void LuaStack::pushLightUserData(void* lpData)
	{
		LUA_ASSERT(lpData);
		lua_pushlightuserdata(m_lpLua->getState(),lpData);
	}
	void LuaStack::pushClosure(int (*lpFunc)(lua_State*), int nargs)
	{
		LUA_ASSERT(lpFunc);
		lua_pushcclosure(m_lpLua->getState(),lpFunc,nargs);
	}
	void LuaStack::pushFunction(int (*lpFunc)(lua_State*))
	{
		LUA_ASSERT(lpFunc);
		lua_pushcfunction(m_lpLua->getState(), lpFunc);
	}

	void LuaStack::getGlobal(const char* name)
	{
		lua_getglobal(m_lpLua->getState(), name);
	}
	int LuaStack::getInteger(int idx)
	{
		return lua_tointeger(m_lpLua->getState(),idx);
	}
	bool LuaStack::getBool(int idx)
	{
		return (lua_toboolean(m_lpLua->getState(),idx))?true:false;
	}
	double LuaStack::getNumber(int idx)
	{
		return lua_tonumber(m_lpLua->getState(),idx);
	}
	const char* LuaStack::getString(int idx)
	{
		return lua_tostring(m_lpLua->getState(),idx);
	}
	void* LuaStack::getUserData(int idx)
	{
		return getUserData(m_lpLua->getState(), idx);
	}
	void LuaStack::getField(int idx, const char* name)
	{
		lua_getfield(m_lpLua->getState(), idx, name);
	}
	LuaStack::CFunc LuaStack::getFunction(int idx)
	{
		return lua_tocfunction(m_lpLua->getState(), idx);
	}
	void LuaStack::getupvalue(int idx, int UpIdx)
	{
		lua_getupvalue(m_lpLua->getState(), idx, UpIdx);
	}


	void* LuaStack::checkUserData(int idx, const char* name)
	{
		return checkUserData(m_lpLua->getState(), idx, name);
	}
	LuaTable LuaStack::getMetaTable(int idx)
	{
		lua_getmetatable(m_lpLua->getState(), idx);
		int iRef = luaL_ref(m_lpLua->getState(),LUA_REGISTRYINDEX);
		return LuaTable(m_lpLua, iRef);
	}


	bool LuaStack::isUserData(int idx)
	{
		return (lua_isuserdata(m_lpLua->getState(), idx) == 1);
	}
	bool LuaStack::isInteger(int idx)
	{
		return (lua_isnumber(m_lpLua->getState(), idx) == 1);
	}
	bool LuaStack::isNumber(int idx)
	{
		return (lua_isnumber(m_lpLua->getState(), idx) == 1);
	}
	bool LuaStack::isString(int idx)
	{
		return (lua_isstring(m_lpLua->getState(), idx) == 1);
	}
	bool LuaStack::isBoolean(int idx)
	{
		return (lua_isstring(m_lpLua->getState(), idx) == 1);
	}
	bool LuaStack::isNil(int idx)
	{
		return (lua_isnil(m_lpLua->getState(), idx) == 1);
	}
	bool LuaStack::isTable(int idx)
	{
		return (lua_istable(m_lpLua->getState(), idx) == 1);
	}
	bool LuaStack::isFunction(int idx)
	{
		return (lua_isfunction(m_lpLua->getState(), idx) == 1);
	}

	void LuaStack::loadFile(const char* lpFile)
	{
		int iResult = luaL_loadfile(m_lpLua->getState(), lpFile);
		if(iResult != 0)
			LuaError::handleError(m_lpLua->getState());
	}
	void LuaStack::pcall(int nargs, int nreturn)
	{
		int iResult = lua_pcall(m_lpLua->getState(), nargs, nreturn, 0);
		if(iResult != 0)
			LuaError::handleError(m_lpLua->getState());
	}


	void* LuaStack::getUserData(lua_State* lpState, int idx)
	{
		return lua_touserdata(lpState,idx);
	}
	void* LuaStack::checkUserData(lua_State* lpState, int idx, const char* name)
	{
		return luaL_testudata(lpState, idx, name);
	}

}